package com.gillion.grule.client.sync;

import com.google.common.collect.Maps;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class RuleCacheProvider<T extends RulePackage> implements RuleProvider
{
    private static final Logger log = LoggerFactory.getLogger(RuleCacheProvider.class);

    protected Map<String, T> localCache = Maps.newConcurrentMap();
    protected Map<String, String> ruleVersionReferences = Maps.newConcurrentMap();



    public T getRule(String groupId, String artifactId) {
        String uniqueKey = artifactId;
        //1） 缓存不为空
        if (this.localCache.containsKey(uniqueKey)) {
            log.info("从缓存获取规则包配置.....................");
            RulePackage rulePackage = (RulePackage)this.localCache.get(uniqueKey);
            String currentVersion = this.ruleVersionReferences.get(uniqueKey);
            //比较缓存规则包的版本和最新版本比较，不一致则加载新的规则包
            if (!StringUtils.equals(rulePackage.getVersion(), currentVersion)) {
                rulePackage = (RulePackage)loadRule(groupId, artifactId, currentVersion);
                this.localCache.put(uniqueKey, (T)rulePackage);
                this.ruleVersionReferences.put(uniqueKey, rulePackage.getVersion());
            }

        } else {
            String currentVersion = this.ruleVersionReferences.get(uniqueKey);
            if (currentVersion != null) {
                log.info("重新获取规则包配置.....................");
                T rulePackage = loadRule(groupId, artifactId, currentVersion);
                log.info("远程服务配置数量：" + rulePackage.getRemoteConfig().size() + "，groovy脚本配置数：" + rulePackage.getGroovyShellConfigs().size());
                this.localCache.put(uniqueKey, rulePackage);
                this.ruleVersionReferences.put(uniqueKey, rulePackage.getVersion());
            }
        }
        DroolsRulePackage result = ((DroolsRulePackage)this.localCache.get(uniqueKey)).clone();
        return (T)result;
    }


    protected void refreshVersionReference(String artifactId, String version) {
        String uniqueKey = artifactId;
        this.ruleVersionReferences.put(uniqueKey, version);
    }

    protected void removeVersionReference(String artifactId) {
        String uniqueKey = artifactId;
        this.ruleVersionReferences.remove(uniqueKey);
    }

    abstract T loadRule(String paramString1, String paramString2, String paramString3);
}
